package modules.sys.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import luxing.common.controller.BaseController;
import luxing.exception.BusinessException;
import luxing.hibernate.CriteriaQuery;
import luxing.util.CriteriaQueryUtil;
import luxing.util.LoginUserUtil;
import luxing.util.SecretUtil;
import luxing.util.StringUtil;
import luxing.util.ValidatorUtil;
import luxing.web.model.ComboTree;
import luxing.web.model.DataGrid;
import luxing.web.model.Result;
import luxing.web.model.SortDirection;
import luxing.web.model.ValidResult;
import manage.sys.entity.Menu;
import manage.sys.service.MenuService;
import manage.tenant.entity.Tenant;
import manage.tenant.service.TenantService;
import modules.sys.entity.Log;
import modules.sys.entity.User;
import modules.sys.service.LogService;
import modules.sys.service.UserService;

/**
 * 用户管理
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("userController")
public class UserController extends BaseController {

	private static final Logger logger = Logger.getLogger(UserController.class);

	@Autowired
	private UserService userService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private TenantService tenantService;
	@Autowired
	private LogService logService;

	/**
	 * 列表页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "index")
	public ModelAndView index() {
		return new ModelAndView("modules/sys/user-list");
	}

	/**
	 * 列表数据
	 * 
	 * @param user
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@RequestMapping(params = "list")
	public void list(User user, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
		try {
			CriteriaQuery cq = new CriteriaQuery(User.class, dataGrid);
			cq.createAlias("tenantList", "tenants");
			cq.eq("tenants.id", LoginUserUtil.getLoginUser().getTenantId());
			CriteriaQueryUtil.assembling(cq, user, request.getParameterMap());
			cq.add();
			userService.listByPage(cq, true);
			listView(response, dataGrid);
		} catch (Exception e) {
			logger.error("用户查询失败", e);
			throw new BusinessException("用户查询失败", e);
		}
	}

	/**
	 * 增加页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goAdd")
	public ModelAndView goAdd(HttpServletRequest req) {
		return new ModelAndView("modules/sys/user-add");
	}

	/**
	 * 增加
	 * 
	 * @param user
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doAdd")
	@ResponseBody
	public Result doAdd(User user, HttpServletRequest request) {
		String msg = null;
		try {
			// 用户状态判断
			User userDB = userService.getByPhone(user.getPhone());
			if (userDB != null) {
				// 用户已存在
				Tenant tenant = new Tenant();
				tenant.setId(LoginUserUtil.getLoginUser().getTenantId());
				userDB.getTenantList().add(tenant);
				List<Menu> menuList = menuService.listByUser(userDB.getId());
				userDB.setMenuList(menuList);
				userService.saveOrUpdate(userDB);
			} else {
				List<Tenant> tenantList = new ArrayList<Tenant>();
				Tenant tenant = new Tenant();
				tenant.setId(LoginUserUtil.getLoginUser().getTenantId());
				tenantList.add(tenant);
				user.setTenantList(tenantList);
				user.setPassword(SecretUtil.encrypt(user.getPhone(), user.getPassword(), SecretUtil.getStaticSalt()));
				// bean校验
				msg = ValidatorUtil.validate(user);
				if (StringUtils.isNotBlank(msg)) {
					return Result.error(msg);
				}
				userService.save(user);
			}
			msg = "用户\"" + user.getName() + "\"增加成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_ADD);
		} catch (Exception e) {
			msg = "用户\"" + user.getName() + "\"增加失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 修改页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goUpdate")
	public ModelAndView goUpdate(User user, HttpServletRequest req) {
		if (StringUtils.isNotBlank(user.getId())) {
			user = userService.get(User.class, user.getId());
			req.setAttribute("userPage", user);
		}
		return new ModelAndView("modules/sys/user-update");
	}

	/**
	 * 用户信息页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goInfo")
	public ModelAndView goInfo(HttpServletRequest req) {
		User user = LoginUserUtil.getUser();
		req.setAttribute("userPage", user);
		return new ModelAndView("modules/sys/user-info");
	}

	/**
	 * 密码重置页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goPassword")
	public ModelAndView goPassword(User user, HttpServletRequest req) {
		if (StringUtils.isNotBlank(user.getId())) {
			user = userService.get(User.class, user.getId());
		} else {
			user = LoginUserUtil.getUser();
		}
		req.setAttribute("userPage", user);
		return new ModelAndView("modules/sys/user-password");
	}

	/**
	 * 权限页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goAuth")
	public ModelAndView goAuth(User user, HttpServletRequest req) {
		req.setAttribute("userId", user.getId());
		return new ModelAndView("modules/sys/user-auth");
	}

	/**
	 * 密码重置
	 * 
	 * @param user
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doPassword")
	@ResponseBody
	public Result doPassword(User user, HttpServletRequest request) {
		String msg = null;
		try {
			List<Tenant> tenantList = tenantService.listByUser(user.getId());
			user.setTenantList(tenantList);
			List<Menu> menuList = menuService.listByUser(user.getId());
			user.setMenuList(menuList);
			user.setPassword(SecretUtil.encrypt(user.getPhone(), user.getPassword(), SecretUtil.getStaticSalt()));
			// bean校验
			msg = ValidatorUtil.validate(user);
			if (StringUtils.isNotBlank(msg)) {
				return Result.error(msg);
			}
			userService.updatePassword(user);
			msg = "用户\"" + user.getName() + "\"密码重置成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_UPDATE);
		} catch (Exception e) {
			msg = "用户\"" + user.getName() + "\"密码重置失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 修改
	 * 
	 * @param user
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doUpdate")
	@ResponseBody
	public Result doUpdate(User user, HttpServletRequest request) {
		String msg = null;
		try {
			List<Tenant> tenantList = tenantService.listByUser(user.getId());
			user.setTenantList(tenantList);
			List<Menu> menuList = menuService.listByUser(user.getId());
			user.setMenuList(menuList);
			// bean校验
			msg = ValidatorUtil.validate(user);
			if (StringUtils.isNotBlank(msg)) {
				return Result.error(msg);
			}
			userService.saveOrUpdate(user);
			msg = "用户\"" + user.getName() + "\"修改成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_UPDATE);
		} catch (Exception e) {
			msg = "用户\"" + user.getName() + "\"修改失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doAuth")
	@ResponseBody
	public Result doAuth(HttpServletRequest request) {
		String msg = null;
		User user = null;
		try {
			String userId = request.getParameter("userId");
			String authIds = request.getParameter("authIds");
			// 不能修改自己权限
			if (userId.equals(LoginUserUtil.getUser().getId())) {
				return Result.error("不能修改自己权限");
			}
			user = userService.get(User.class, userId);
			Set<String> authIdSet = StringUtil.splitToSet(",", authIds);
			// 菜单
			List<Menu> allMenuList = menuService.listAll(Menu.class);
			List<Menu> menuList = new ArrayList<Menu>();
			Map<String, Menu> menuMap = new HashMap<String, Menu>();
			for (Menu menu : allMenuList) {
				menuMap.put(menu.getId(), menu);
			}
			// 操作
			for (String id : authIdSet) {
				if (menuMap.get(id) != null) {
					menuList.add(menuMap.get(id));
				}
			}
			user.setMenuList(menuList);
			userService.saveOrUpdate(user);
			msg = "用户\"" + user.getName() + "\"权限设置成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_UPDATE);
		} catch (Exception e) {
			msg = "用户\"" + user.getName() + "\"权限设置失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 设置权限
	 * 
	 * @param request
	 * @param comboTree
	 * @return
	 */
	@RequestMapping(params = "userAuthTree")
	@ResponseBody
	public List<ComboTree> userAuthTree(HttpServletRequest request, ComboTree comboTree) {
		String userId = request.getParameter("userId");
		CriteriaQuery cq = new CriteriaQuery(Menu.class);
		cq.isNull("parentMenu");
		cq.eq("type", Menu.TYPE_TENANT);
		cq.addOrder("order", SortDirection.asc);
		cq.add();
		List<Menu> menuList = menuService.listByCriteria(cq);
		// 拥有权限菜单ID
		List<String> userMenuIdList = menuService.listMenuIdsByUser(userId);
		// 拥有权限操作ID
		List<String> authIdList = new ArrayList<>();
		authIdList.addAll(userMenuIdList);

		List<ComboTree> comboTrees = new ArrayList<ComboTree>();
		for (Menu menu : menuList) {
			ComboTree tree = assemblingUserAuthTree(menu, authIdList);
			comboTrees.add(tree);
		}
		return comboTrees;
	}

	private ComboTree assemblingUserAuthTree(Menu menu, List<String> authIdList) {
		ComboTree tree = new ComboTree();
		tree.setId(menu.getId());
		tree.setText(menu.getName());
		if (authIdList.contains(menu.getId())) {
			tree.setChecked(true);
		}
		if (CollectionUtils.isNotEmpty(menu.getChildMenus())) {
			// 有子菜单
			List<ComboTree> childComboTrees = new ArrayList<ComboTree>();
			tree.setChecked(false);
			tree.setState("closed");
			for (Menu childMenu : menu.getChildMenus()) {
				ComboTree childComboTree = assemblingUserAuthTree(childMenu, authIdList);
				childComboTrees.add(childComboTree);
			}
			tree.setChildren(childComboTrees);
		}
		return tree;
	}

	/**
	 * 删除
	 * 
	 * @return
	 */
	@RequestMapping(params = "doDel")
	@ResponseBody
	public Result doDel(User user, HttpServletRequest request) {
		String msg = null;
		try {
			// 不能删除自己
			if (user.getId().equals(LoginUserUtil.getUser().getId())) {
				return Result.error("不能删除自己");
			}
			user = userService.get(User.class, user.getId());
			// 如果用户关联多个租户,则解除当前租户关联关系
			if (user.getTenantList().size() > 1) {
				List<Tenant> tenantList = new ArrayList<Tenant>();
				for (Tenant tenant : user.getTenantList()) {
					if (!tenant.getId().equals(LoginUserUtil.getLoginUser().getTenantId())) {
						tenantList.add(tenant);
					}
				}
				user.setTenantList(tenantList);
				userService.saveOrUpdate(user);
			} else {
				// 用户只属于一个租户，物理删除
				userService.delete(user);
			}
			msg = "用户\"" + user.getName() + "\"删除成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_DEL);
		} catch (Exception e) {
			msg = "用户\"" + user.getName() + "\"删除失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 手机change ajax
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(params = "phoneChange")
	@ResponseBody
	public Result phoneChange(HttpServletRequest req) {
		Result result = new Result();
		Map<String, Object> attributes = new HashMap<String, Object>();
		String phone = req.getParameter("phone");
		User user = userService.getByPhone(phone);
		if (user != null) {
			attributes.put("exist", "yes");
			attributes.put("userName", user.getName());
		} else {
			attributes.put("exist", "no");
		}
		result.setAttributes(attributes);
		return result;
	}

	/**
	 * 手机校验
	 */
	@RequestMapping(params = "validPhone")
	@ResponseBody
	public ValidResult validPhone(HttpServletRequest request) {
		ValidResult result = new ValidResult();
		String tenantId = request.getParameter("tenantId");
		if (StringUtils.isBlank(tenantId)) {
			tenantId = LoginUserUtil.getLoginUser().getTenantId();
		}
		String phone = request.getParameter("phone");
		User user = userService.getByTenantAndPhone(tenantId, phone);
		if (user != null) {
			result.setInfo("手机已存在");
			result.setStatus("n");
		}
		return result;
	}

	/**
	 * 弱密码校验
	 */
	@RequestMapping(params = "validPassword")
	@ResponseBody
	public ValidResult validPassword(HttpServletRequest request) {
		ValidResult result = new ValidResult();
		String password = request.getParameter("password");
		// 弱密码校验
		if (SecretUtil.weakPassword(password)) {
			result.setInfo("密码太简单");
			result.setStatus("n");
		}
		return result;
	}

}